﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using Lync.Widget.Library.Configuration;
using Lync.Widget.Library.Presentation.Entities;
using ILanguagePack = Lync.Widget.Library.Presentation.Entities.ILanguagePack;
using ILanguageResource = Lync.Widget.Library.Presentation.Entities.ILanguageResource;

namespace Lync.Widget.Library.Presentation.Models
{
    public class LanguagePacksModel : ILanguagePacksModel
    {
        const string ConfigurationPath = @"\Configuration\LanguagePack.config";

        public XElement GetConfigurationXml()
        {
            try
            {
                var path = HttpContext.Current.Server.MapPath(ConfigurationPath);
                return File.Exists(path) ? XElement.Load(path) : null;
            }
            catch (Exception exception)
            {                
                throw new Exception(String.Format("Failed to load configuration file: {0}",exception));
            }
            
        }

        public IList<ILanguagePack> GetAll()
        {
            if (GetConfigurationXml() == null) return null;

            var configurationSection = LanguagePacksConfigurationSection.Load();
            var packs = configurationSection.LanguagePacks;

            var result = new List<ILanguagePack>();

            if (packs != null)
            {
                foreach (var languagePack in packs)
                {
                    var pack = new LanguagePack
                                   {
                                       IsDefault = languagePack.IsDefault,
                                       Language = languagePack.Language,
                                       Resources = new  List<ILanguageResource>()
                                   };

                    foreach (var languageResource in languagePack.Resources)
                    {
                        var resource = new LanguageResource
                                           {                                               
                                               Key = languageResource.Key,
                                               Name = languageResource.Name,
                                               Value = languageResource.Value,
                                           };

                        pack.Resources.Add(resource);
                    }

                    result.Add(pack);
                }
            }

            return result.OrderBy(r => r.Language).ToList();
        }

        public ILanguagePack Get(string language)
        {
            var languagepacks = GetAll();

            return languagepacks != null ? languagepacks.SingleOrDefault(p => p.Language == language) : null;
        }

        public ILanguagePack GetDefault()
        {
            var languagepacks = GetAll();

            return languagepacks != null ? languagepacks.SingleOrDefault(p => p.IsDefault) : null;
        }

        public void Save(string language, IList<ILanguageResource> resources, bool isDefault)
        {
            var toSave = new List<ILanguagePack>();

            var pack = new LanguagePack
                           {
                               IsDefault = isDefault,
                               Language = language,
                               Resources = resources,
                           };
            
            toSave.Add(pack);

            var configurationSection = LanguagePacksConfigurationSection.Load();
            var languagePacksFromConfig = configurationSection.LanguagePacks;

            var packFromConfig = languagePacksFromConfig.SingleOrDefault(p => p.Language == language);

            if (packFromConfig != null)
            {
                languagePacksFromConfig.Remove(packFromConfig);
            }

            foreach (var languagePack in languagePacksFromConfig)
            {
                toSave.Add(new LanguagePack
                               {
                                   Language = languagePack.Language,
                                   IsDefault = languagePack.IsDefault,
                                   Resources = languagePack.Resources.Select(r => new LanguageResource
                                                                                      {
                                                                                          Key = r.Key,
                                                                                          Name = r.Name,
                                                                                          Value = r.Value
                                                                                      }).Cast<ILanguageResource>().ToList()
                               } );
            }


            toSave = toSave.OrderByDescending(p => p.IsDefault).ToList();

            var languagesElement = new XElement("Languages");

            foreach (var languagePack in toSave)
            {
                languagesElement.Add(new XElement("Language",
                                            new XElement("Resources", languagePack.Resources.Select(resource =>
                                                            new XElement("Resource",
                                                            new XAttribute("name", resource.Name),
                                                            new XAttribute("key", resource.Key),
                                                            new XAttribute("value", resource.Value)))),
                                            new XAttribute("id", languagePack.Language),
                                            new XAttribute("isdefault", languagePack.IsDefault)));

            }

            var root = new XElement("languagePacks", languagesElement);

            root.Save(HttpContext.Current.Server.MapPath(ConfigurationPath));
        }
    }
}